#include <iostream>
#include <vector>
#include <string>
#include <thread>
#include <memory>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <cstring>
#include <algorithm>

const int MAX_CLIENTS = 1000;  // 最大客户端数
const int SERVER_PORT = 7711;  // 服务器端口

class Client {
public:
    Client(int fd) : fd(fd), nickname("user:" + std::to_string(fd)) {}
    int fd;  // 客户端套接字文件描述符
    std::string nickname;  // 客户端昵称
};

class ChatServer {
public:
    ChatServer() : serversock(-1) {
        clients.reserve(MAX_CLIENTS);
    }

    void start() {
        serversock = createTCPServer(SERVER_PORT);
        std::cout << "服务器正在端口 " << SERVER_PORT << " 上运行" << std::endl;

        while (true) {
            int clientSocket = acceptClient(serversock);
            clients.emplace_back(std::make_unique<Client>(clientSocket));
            std::cout << "新客户端连接: " << clientSocket << std::endl;
            std::thread clientThread(&ChatServer::handleClient, this, clientSocket);
            clientThread.detach();
        }
    }

private:
    int serversock;  // 服务器套接字文件描述符
    std::vector<std::unique_ptr<Client>> clients;  // 客户端列表

    int createTCPServer(int port) {
        int s, yes = 1;
        struct sockaddr_in sa;

        if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) return -1;
        setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));

        memset(&sa, 0, sizeof(sa));
        sa.sin_family = AF_INET;
        sa.sin_port = htons(port);
        sa.sin_addr.s_addr = htonl(INADDR_ANY);

        if (bind(s, (struct sockaddr*)&sa, sizeof(sa)) == -1 ||
            listen(s, 511) == -1)
        {
            close(s);
            return -1;
        }
        return s;
    }

    int acceptClient(int server_socket) {
        int s;
        while (1) {
            struct sockaddr_in sa;
            socklen_t slen = sizeof(sa);
            s = accept(server_socket, (struct sockaddr*)&sa, &slen);
            if (s == -1) {
                if (errno == EINTR)
                    continue;
                else
                    return -1;
            }
            break;
        }
        return s;
    }

    // 处理客户端连接
    void handleClient(int clientSocket) {
        std::string buf;
        std::string nickname;  // 存储客户端昵称

        std::string welcome_msg="欢迎来到简易聊天室！请使用 /nick <昵称> 来设置您的昵称。\n";

        write(clientSocket, welcome_msg.c_str(), welcome_msg.length());

        while (true) {
            buf.clear();
            char buffer[256];
            int nread = recv(clientSocket, buffer, sizeof(buffer), 0);

            if (nread <= 0) {
                close(clientSocket);
                removeClient(clientSocket);
                std::cout << "客户端断开连接: " << clientSocket << std::endl;
                break;
            }

            buf.assign(buffer, nread);

            if (buf[0] == '/') {
                if (buf.compare(0, 5, "/nick") == 0) {
                    setNickname(clientSocket, buf, nickname);  // 传递客户端昵称
                } else {
                    const char* errmsg = "不支持的命令\n";
                    send(clientSocket, errmsg, strlen(errmsg), 0);
                }
            } else {
                std::string message = nickname + "> " + buf;
                broadcast(message, clientSocket);
            }
        }
    }

    // 设置客户端昵称
    void setNickname(int clientSocket, const std::string& buf, std::string& nickname) {
        size_t spacePos = buf.find(' ');
        if (spacePos != std::string::npos) {
			size_t end = buf.find_last_not_of(" \n\r\t");
            std::string newNickname = buf.substr(spacePos + 1, end - spacePos);
            nickname = newNickname;  // 更新客户端昵称
            std::string message = "您的昵称已更改为 " + newNickname + "\n";
            send(clientSocket, message.c_str(), message.length(), 0);
        }
    }

    // 广播消息给所有客户端
    void broadcast(const std::string& message, int senderSocket) {
		std::cout << message;
        for (auto& client : clients) {
            if (client->fd != senderSocket) {
                write(client->fd, message.c_str(), message.length());
            }
        }
    }

    // 移除客户端
    void removeClient(int clientSocket) {
        clients.erase(std::remove_if(clients.begin(), clients.end(),
            [clientSocket](const std::unique_ptr<Client>& client) {
                return client->fd == clientSocket;
            }), clients.end());
    }
};

int main() {
    ChatServer server;
    server.start();
    return 0;
}

